週刊Automatineマガジン 1.AutomatineでのCoroutine


概要

毎号集めても何もない。ドキュメント作る時の備忘録。

今回は、AutomatineでのCoroutineの指針と、Coroutineで扱うパラメータ解説。



Coroutineの指針


Coroutineを超えてパラメータを扱いたい、、という時にはInitialTypeParamのパラメータを使おう

1.ロックオン

2.ロックしてあるやつを殴りに行く

こういう時には、InitialTypeParam自体や、そのプロパティ、値に「ロックした敵」というパラメータを持つといい。

実行中の各Coroutineでインスタンスを共有できるので、ロックした敵があったらそのIdを使って~みたいな書き方ができる。


Autoを超えてパラメータを扱いたい、、という時にも、contextのパラメータを使おう

初期化時に渡すと楽。


var context = new Context();

auto = new Something<Context, Other>(frame, context);


Coroutineは部品のように細かく分けて作ってもいいけど、大雑把に作って後で割るのもOK

e.g. 

一番近い敵の方を向く

敵まで歩いていく


最初はゴチャッと作っちゃっても問題ない。

e.g.

一番近い敵の方に向いてそのまま歩いていって殴る


ただし、名前とコメントをつけるようにしよう。


Coroutineの役割の分解は、コードがあんまり分散してないので、あとで簡単にできる。

まずは動くものを作って、そのあと切り分けるのがカンタン。



Coroutineで扱うパラメータ解説

Coroutineの初期値とパラメータについて

Timeline上に複数のTackを置いた場合、そのTackについているCoroutineが順に実行されるわけだが。

実行されるCoroutineには、次の2つのパラメータが入る。


1.initialParam、すべてのCoroutineから参照/設定ができるパラメータ

2.updateParam、auto.Updateの度に更新されるパラメータ



1.initialParam、すべてのCoroutineから参照/設定ができるパラメータ

new時にInitialParamTypeで型指定、initialParamとして渡せる値は、


・Autoのnewの時に、全Coroutineへと渡るパラメータになる

・全Coroutineからの変更が可能


という特性を持っている。


具体例として、次のようなAutoを初期化するコードがあると、


auto = new Auto<string, int>(frame, “初期値”);


InitialParamType には string型がセットされ、コンストラクタの第二引数 InitialTypeのパラメータにもstring型の値が入っている。



こうすると、このAutoのすべてのTimelineのすべてのTackに対して、Coroutine動作時に渡されるパラメータとして “初期値” という文字列が入る。


public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {

public IEnumerator TheCoroutine1 (InitialParamType initialParam) {

// ここで、initialParamの型は string になっている。 キャストして取り出すことができる。

var str = initialParam as string;


// この値は、このTimelineにセットされているどのCoroutineでも、そのTimeliineが所属するAutoを初期化した値になっている。

if (str == “初期値”) {

// true.

}

yield return null;

}

}



もし、InitialParamに自分で定義したクラスのインスタンスを入れた場合、そのインスタンスはそのAuto内のすべてのCoroutineに引き継がれる。


次のような[パラメータのパッケージ]をクラスとして定義してInitialTypeParamとして使う場合、

public class Params {

public string message;

}


auto = new Auto<Params, int>(frame, new Params());


ここで new Params() したインスタンスが、そのAutoの中のすべてのCoroutineからアクセス可能になる。

どこかのCoroutineで変更を加えると、その変更は他のCoroutineからも参照、変更できる。


次のCoroutine TheCoroutine2で、Paramsインスタンスのmessageという変数に”hello!!”という文字列をセットすると、

public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {

public IEnumerator TheCoroutine2 (InitialParamType initialParam) {

var params = initialParam as Params;

params.message = “hello!!”;

yield return null;

}

}


その後に実行されるCoroutineからは、その変更が把握できる。


public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {

public IEnumerator TheCoroutine3 (InitialParamType initialParam) {

var params = initialParam as Params;

if (params.message == “hello!!”;) {

// true.

}

yield return null;

}

}


こんな感じで、initialParamには次のような性質がある。

・Autoのnewの時に、全Coroutineへと渡るパラメータになる

・全Coroutineからの参照、変更が可能



2.updateParam、auto.Updateの度に更新されるパラメータ

Coroutineには、this.updateParam, this.frame などのパラメータが定義されている。

これらの値はAutoのアップデートを行うタイミングでセットすることができる。

例えばこんなクラスを用意し、

public class Params {

public string message;

}


Autoを次のように初期化した場合、


auto = new Auto<string, Params>(frame, “初期化”);


UpdateParamTypeには、Params型を指定してあり、

この後に実行するauto.Updateで、第二引数としてParams型のインスタンスを実行中のCoroutineへと渡すことができる。


var updateParam = new Params();

updateParam.message = “World!” + frame;

auto.Update(frame,  updateParam)

frame++;

このUpdateでは、実行開始のタイミング or 実行中のすべてのCoroutineへと、updateParamが入力される。


先ほどのUpdateを実行すると、Coroutineの中のパラメータはこんな感じになる。


public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {

public IEnumerator TheCoroutine4 (InitialParamType initialParam) {

var updateParams = this.updateParam as Params;

if (updateParams.message.StartsWith(“World!”)) {

// true.

}


yield return null;

}

}


また、複数回実行できるようなCoroutineの場合、毎回実行されるたびにupdateParamが更新される。


public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {

public IEnumerator TheCoroutine4 (InitialParamType initialParam) {


while (true) {

var updateParams = this.updateParam as Params;


Debug.Log(“updateParams.message:” + updateParams.message); // updateParams.message:World!フレーム数 (フレーム数部分は変動


yield return null;

}

}

}


ざっくり書くと、Updateを行うと、実行状態になった全Coroutineにその値がセットされ実行される。


auto.Update(frame, obj) ――> CoroutineA {this.updateParamにはobjが入っている}

――> CoroutineB {this.updateParamにはobjが入っている}

――> CoroutineC {this.updateParamにはobjが入っている}



Coroutine中の定義済みの値には、次のものがある。


・int frame

Update関数で入力したframeが入る。


・UpdateParamType updateParam

Update関数で入力したupdateParamが入る。


・loadCount

このCoroutineの実行回数が入っている。初回0。



まとめ

Coroutineに入ってくるパラメータ、

・一つのインスタンスをひき回せるInitialParamType

・毎フレーム更新されるUpdateParamType

の2つがある。


必要に合わせて使うといいと思う。